#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "util.h"
using namespace std;

int k;
string str_k;
unsigned long long int n;
unsigned long long int union_index;
unsigned long long int* arr;
double running_progress;


ofstream sim_union_filewrite;
ofstream all_union_filewrite;
ofstream min_value_filewrite;

string integer_to_string(int value)
{
	string str = "";
	int tmp;
	char ch;
	while (value)
	{
		tmp = value % 10;
		ch = '0' + tmp;
		str = ch + str;
		value /= 10;
	}
	if (str.length() == 0)
	{
		str = "0";
	}
	return str;
}

int string_to_integer (string s)
{
	stringstream ss;
	ss << s << endl;
	int ans;
	ss >> ans;
	return ans;
}

int main(int argc, char* argv[])
{
	string argv_str = argv[1];
	k = string_to_integer(argv_str);
	cout << k << endl;
	/*
		cout << "Input K: ";
		cin >> k;
	*/
	arr = new unsigned long long int[k];
	n = pow_2(k);

	// ---- 分配输出文件名称
	str_k = integer_to_string(k);
	// string file_name = str_k + "_sim.txt";
	sim_union_filewrite.open(&(str_k + "_sim.txt")[0], ios::out);
	all_union_filewrite.open(&(str_k + "_all.txt")[0], ios::out);
	min_value_filewrite.open(&(str_k + "_min.txt")[0], ios::out);


	for (union_index = 1; union_index <= n; union_index += 2)
	{
		if ( (union_index + 1) % 10000 == 0)
		{
			running_progress = (double)union_index / n;
			for (int i = 0; i <= 100; i++)
			{
				cout << "\b";
			}
			cout << running_progress * 100 << "%";
		}

		for (int i = 0; i < k; i++)
		{
			unsigned long long int tmp = union_index * pow_2(i);
			tmp %= (n - 1);
			if (tmp <= 0)
			{
				tmp += (n - 1);
			}
			arr[i] = tmp;
		}

		// ---- 检测是不是sim_union，并输出
		bool is_sim_union = true;
		for (int i = 1; i < k; i++)
		{
			if (arr[i] <= arr[0])
			{
				is_sim_union = false;
			}
		}
		if (is_sim_union)
		{
			for (int i = 0; i < k; i++)
			{
				// ---- 输出到文件
				sim_union_filewrite << arr[i] << " ";
			}
			sim_union_filewrite << "\n";
		}


		// ---- 检测是不是all_union，并输出
		bool is_all_union = true;
		for (int i = 1; i < k; i++)
		{
			if (arr[i] < arr[0])
			{
				is_all_union = false;
			}
		}
		if (is_all_union)
		{
			for (int i = 0; i < k; i++)
			{
				// ---- 输出到文件
				all_union_filewrite << arr[i] << " ";
			}
			all_union_filewrite << "\n";
			min_value_filewrite << arr[0] << " ";
		}

	}
	min_value_filewrite << "\n";

	sim_union_filewrite.close();
	all_union_filewrite.close();
	min_value_filewrite.close();

	cout << "\n=================================";
	cout << "Done=================================\n\n\n";

	return 0;
}

